package top.continew.minithreadpool.ui.cyberpunkUi;


import top.continew.minithreadpool.concurrent.ThreadPool;
import top.continew.minithreadpool.concurrent.ThreadPoolExecutor;
import top.continew.minithreadpool.concurrent.ThreadPoolFactory;
import top.continew.minithreadpool.factory.DefaultThreadFactory;
import top.continew.minithreadpool.policy.AbortPolicy;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class CyberpunkThreadPoolVisualizer extends JFrame {
    // 赛博朋克配色
    public static final Color BACKGROUND = new Color(10, 10, 20); // 深空黑
    public static final Color NEON_PINK = new Color(255, 0, 128); // 霓虹粉
    public static final Color NEON_BLUE = new Color(0, 195, 255); // 霓虹蓝
    public static final Color NEON_GREEN = new Color(0, 255, 163); // 霓虹绿
    public static final Color NEON_PURPLE = new Color(180, 0, 255); // 霓虹紫
    public static final Color TEXT_COLOR = new Color(220, 220, 255); // 浅紫灰

    private ThreadPoolExecutor threadPool;
    private Timer timer;

    // UI 组件
    private JLabel activeThreadsLabel;
    private JLabel queueSizeLabel;
    private JLabel completedTasksLabel;
    private JLabel stateLabel;

    private CyberTaskQueuePanel cyberTaskQueuePanel;
    private JTextArea logArea;

    private CyberButton startButton;
    private CyberButton stopButton;
    private CyberButton submitButton;

    private JSpinner taskCountSpinner;
    private JSlider corePoolSizeSlider;
    private JSlider maxPoolSizeSlider;

    public CyberpunkThreadPoolVisualizer() {
        super("赛博线程池 - 教学工具");
        setSize(1200, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 初始化线程池
        threadPool = ThreadPoolFactory.createFixedThreadPool(4);

        // 创建UI组件
        createUI();

        // 启动状态更新定时器
        startStatusTimer();

        // 设置窗口居中
        setLocationRelativeTo(null);
    }

    private void createUI() {
        // 主面板 - 使用赛博朋克背景
        JPanel mainPanel = new CyberPanel();
        mainPanel.setLayout(new BorderLayout());
        mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        // 标题
        JLabel titleLabel = new JLabel("赛博线程池教学工具", SwingConstants.CENTER);
        titleLabel.setFont(new Font("OCR A Extended", Font.BOLD, 36));
        titleLabel.setForeground(NEON_BLUE);
        titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 30, 0));
        mainPanel.add(titleLabel, BorderLayout.NORTH);

        // 内容面板
        JPanel contentPanel = new JPanel(new GridLayout(1, 2, 30, 0));
        contentPanel.setOpaque(false);

        // 左侧控制面板
        JPanel leftPanel = new CyberPanel();
        leftPanel.setLayout(new GridLayout(4, 1, 20, 20));

        // 线程池配置面板
        JPanel configPanel = createCyberPanel("线程池配置", NEON_PURPLE);
        configPanel.setLayout(new GridLayout(4, 2, 10, 15));

        JLabel coreSizeText = createCyberLabel("核心线程数:", NEON_GREEN);
        corePoolSizeSlider = createCyberSlider(1, 10, 4);
        JLabel maxSizeText = createCyberLabel("最大线程数:", NEON_GREEN);
        maxPoolSizeSlider = createCyberSlider(1, 10, 4);

        configPanel.add(coreSizeText);
        configPanel.add(corePoolSizeSlider);
        configPanel.add(maxSizeText);
        configPanel.add(maxPoolSizeSlider);

        // 状态面板
        JPanel statusPanel = createCyberPanel("线程池状态", NEON_BLUE);
        statusPanel.setLayout(new GridLayout(4, 2, 10, 15));

        JLabel activeThreadsText = createCyberLabel("活跃线程:", NEON_GREEN);
        activeThreadsLabel = createCyberValueLabel("0", NEON_PINK);
        JLabel queueSizeText = createCyberLabel("队列大小:", NEON_GREEN);
        queueSizeLabel = createCyberValueLabel("0", NEON_PINK);
        JLabel completedTasksText = createCyberLabel("完成任务:", NEON_GREEN);
        completedTasksLabel = createCyberValueLabel("0", NEON_PINK);
        JLabel stateText = createCyberLabel("状态:", NEON_GREEN);
        stateLabel = createCyberValueLabel("运行中", NEON_GREEN);

        statusPanel.add(activeThreadsText);
        statusPanel.add(activeThreadsLabel);
        statusPanel.add(queueSizeText);
        statusPanel.add(queueSizeLabel);
        statusPanel.add(completedTasksText);
        statusPanel.add(completedTasksLabel);
        statusPanel.add(stateText);
        statusPanel.add(stateLabel);

        // 控制按钮面板
        JPanel buttonPanel = createCyberPanel("控制中心", NEON_PINK);
        buttonPanel.setLayout(new GridLayout(4, 1, 15, 15));

        startButton = new CyberButton("启动线程池", NEON_BLUE);
        stopButton = new CyberButton("停止线程池", NEON_PINK);
        submitButton = new CyberButton("提交任务", NEON_GREEN);
        CyberButton resizeButton = new CyberButton("调整线程池", NEON_PURPLE);

        startButton.addActionListener(e -> startThreadPool());
        stopButton.addActionListener(e -> stopThreadPool());
        submitButton.addActionListener(e -> submitTasks());
        resizeButton.addActionListener(e -> resizeThreadPool());

        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);
        buttonPanel.add(submitButton);
        buttonPanel.add(resizeButton);

        // 任务提交面板
        JPanel taskPanel = createCyberPanel("任务控制", NEON_GREEN);
        taskPanel.setLayout(new GridLayout(2, 2, 10, 10));

        JLabel taskCountLabel = createCyberLabel("任务数量:", NEON_BLUE);
        taskCountSpinner = createCyberSpinner(10, 1, 100);

        taskPanel.add(taskCountLabel);
        taskPanel.add(taskCountSpinner);
        taskPanel.add(new JLabel()); // 占位符
        taskPanel.add(new JLabel()); // 占位符

        // 添加面板到左侧
        leftPanel.add(configPanel);
        leftPanel.add(statusPanel);
        leftPanel.add(buttonPanel);
        leftPanel.add(taskPanel);

        // 右侧面板
        JPanel rightPanel = new JPanel(new BorderLayout(0, 30));
        rightPanel.setOpaque(false);

        // 任务队列面板
        BlockingQueue<Runnable> queue = threadPool.getQueue();
        cyberTaskQueuePanel = new CyberTaskQueuePanel(queue);
        JPanel queueWrapper = new CyberPanel();
        queueWrapper.setLayout(new BorderLayout());
        queueWrapper.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(NEON_BLUE, 2), "任务队列"
        ));
        queueWrapper.add(cyberTaskQueuePanel, BorderLayout.CENTER);

        // 日志区域
        JPanel logPanel = createCyberPanel("系统日志", NEON_PURPLE);
        logPanel.setLayout(new BorderLayout());

        logArea = new JTextArea();
        logArea.setEditable(false);
        logArea.setFont(new Font("Consolas", Font.PLAIN, 14));
        logArea.setForeground(TEXT_COLOR);
        logArea.setBackground(new Color(20, 20, 30));
        JScrollPane scrollPane = new JScrollPane(logArea);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        scrollPane.getViewport().setBackground(new Color(20, 20, 30));

        logPanel.add(scrollPane, BorderLayout.CENTER);

        // 添加组件到右侧面板
        rightPanel.add(queueWrapper, BorderLayout.CENTER);
        rightPanel.add(logPanel, BorderLayout.SOUTH);

        // 添加左右面板到内容面板
        contentPanel.add(leftPanel);
        contentPanel.add(rightPanel);

        // 添加内容面板到主面板
        mainPanel.add(contentPanel, BorderLayout.CENTER);

        // 添加主面板到窗口
        add(mainPanel);
    }

    private JPanel createCyberPanel(String title, Color borderColor) {
        JPanel panel = new JPanel();
        panel.setBackground(new Color(20, 20, 30, 200));
        panel.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(borderColor, 2), title
        ));
        ((javax.swing.border.TitledBorder)panel.getBorder())
                .setTitleFont(new Font("OCR A Extended", Font.BOLD, 16));
        ((javax.swing.border.TitledBorder)panel.getBorder())
                .setTitleColor(borderColor);
        return panel;
    }

    private JLabel createCyberLabel(String text, Color color) {
        JLabel label = new JLabel(text);
        label.setForeground(color);
        label.setFont(new Font("OCR A Extended", Font.BOLD, 14));
        label.setHorizontalAlignment(SwingConstants.RIGHT);
        return label;
    }

    private JLabel createCyberValueLabel(String text, Color color) {
        JLabel label = new JLabel(text);
        label.setForeground(color);
        label.setFont(new Font("Consolas", Font.BOLD, 14));
        label.setHorizontalAlignment(SwingConstants.LEFT);
        return label;
    }

    private JSpinner createCyberSpinner(int value, int min, int max) {
        SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, 1);
        JSpinner spinner = new JSpinner(model);
        spinner.setFont(new Font("Consolas", Font.BOLD, 14));
        spinner.setBackground(new Color(30, 30, 40));
        spinner.setForeground(NEON_GREEN);
        spinner.setBorder(BorderFactory.createLineBorder(NEON_BLUE, 1));

        // 自定义编辑器
        JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner);
        editor.getTextField().setBackground(new Color(30, 30, 40));
        editor.getTextField().setForeground(NEON_GREEN);
        editor.getTextField().setCaretColor(NEON_BLUE);
        spinner.setEditor(editor);

        return spinner;
    }

    private JSlider createCyberSlider(int min, int max, int value) {
        JSlider slider = new JSlider(min, max, value);
        slider.setBackground(new Color(20, 20, 30));
        slider.setForeground(NEON_GREEN);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.setMajorTickSpacing((max - min) / 2);
        slider.setMinorTickSpacing(1);
        slider.setFont(new Font("Consolas", Font.PLAIN, 10));
        return slider;
    }

    private void startStatusTimer() {
        timer = new Timer(50, e -> {
            updateStatus();
            cyberTaskQueuePanel.refresh();
        });
        timer.start();
    }

    private void updateStatus() {
        // 更新状态标签
        activeThreadsLabel.setText(String.valueOf(threadPool.getActiveCount()));
        queueSizeLabel.setText(String.valueOf(threadPool.getQueue().size()));
        completedTasksLabel.setText(String.valueOf(threadPool.getCompletedTaskCount()));

        // 更新状态标签
        if (threadPool.isShutdown()) {
            stateLabel.setText("已关闭");
            stateLabel.setForeground(NEON_PINK);
        } else {
            stateLabel.setText("运行中");
            stateLabel.setForeground(NEON_GREEN);
        }
    }

    private void startThreadPool() {
        if (threadPool != null && !threadPool.isShutdown()) {
            log("线程池已在运行中");
            return;
        }

        int coreSize = corePoolSizeSlider.getValue();
        int maxSize = maxPoolSizeSlider.getValue();

        threadPool = new ThreadPool(
                coreSize, maxSize, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(100),
                new DefaultThreadFactory(),
                new AbortPolicy()
        );

        log("线程池已启动 (核心线程: " + coreSize + ", 最大线程: " + maxSize + ")");
    }

    private void stopThreadPool() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池已关闭或未启动");
            return;
        }

        threadPool.shutdown();
        log("线程池关闭中...");

        // 在后台等待线程池关闭
        new Thread(() -> {
            try {
                threadPool.awaitTermination(5, TimeUnit.SECONDS);
                log("线程池已完全关闭");
            } catch (InterruptedException ex) {
                log("线程池关闭被中断");
            }
        }).start();
    }

    private void resizeThreadPool() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池未启动，请先启动线程池");
            return;
        }

        int newCoreSize = corePoolSizeSlider.getValue();
        int newMaxSize = maxPoolSizeSlider.getValue();

        threadPool.setCorePoolSize(newCoreSize);
        threadPool.setMaximumPoolSize(newMaxSize);

        log("线程池已调整 (新核心线程: " + newCoreSize + ", 新最大线程: " + newMaxSize + ")");
    }

    private void submitTasks() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池未启动或已关闭，无法提交任务");
            return;
        }

        int taskCount = (Integer) taskCountSpinner.getValue();
        log("提交 " + taskCount + " 个任务");

        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            threadPool.execute(() -> {
                String threadName = Thread.currentThread().getName();
                log("任务 " + taskId + " 开始执行 (" + threadName + ")");

                try {
                    // 模拟任务执行时间 (1-3秒)
                    int duration = 1000 + (int)(Math.random() * 2000);
                    Thread.sleep(duration);

                    log("任务 " + taskId + " 完成 (" + threadName + ")");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log("任务 " + taskId + " 被中断 (" + threadName + ")");
                }
            });
        }
    }

    private void log(String message) {
        SwingUtilities.invokeLater(() -> {
            logArea.append("> " + message + "\n");
            // 自动滚动到最后一行
            logArea.setCaretPosition(logArea.getDocument().getLength());
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            CyberpunkThreadPoolVisualizer visualizer = new CyberpunkThreadPoolVisualizer();
            visualizer.setVisible(true);
        });
    }
}